#include "crossbit/SYSCALL.h"
#include "crossbit/GLOBAL.h"

using namespace crossbit;

XTMemAddr SYSCALL::sys_brk = 0;
XTMemAddr SYSCALL::original_brk = 0;

XTMemAddr SYSCALL::sys_mmap = 0;

XTInt32 SYSCALL::XTOpen(const XTPStr pathname, XTInt32 flags)
{
		return open(pathname, flags);
}

XTInt32 SYSCALL::XTOpen(const XTPStr pathname, XTInt32 flags, mode_t mode)
{
		return open(pathname, flags, mode);
}

XTInt32 SYSCALL::XTClose(XTInt32 fd)
{
		return close(fd);
}

XTInt32 SYSCALL::XTRead(XTInt32 fd, void *buf, XTInt32 count)
{
		return read(fd, buf, count);
}

XTInt32 SYSCALL::XTWrite(XTInt32 fd, void *buf, XTInt32 count)
{
		return write(fd, buf, count);
}

XTInt32 SYSCALL::XTIoctl(XTInt32 d, XTInt32 request, ...)
{
		return ioctl(d, request);
}

XTInt32 SYSCALL::XTFcntl(XTInt32 fd, XTInt32 cmd, XTInt64 arg)
{
		return fcntl(fd, cmd, arg);
}

XTInt32 SYSCALL::XTExecve(const XTPStr filename , XTPStr * argv , XTPStr * envp){
		return execve( filename , argv , envp );
}

XTInt32 SYSCALL::XTFork(void)
{
		return fork();
}

XTUint32 SYSCALL::XTGetuid()
{
		return getuid();
}

XTUint32 SYSCALL::XTGetgid()
{
		return getgid();
}

XTUint32 SYSCALL::XTGeteuid()
{
		return geteuid();
}

XTUint32 SYSCALL::XTGetegid()
{
		return getegid();
}

XTUint32 SYSCALL::XTGetpid()
{
		return getpid();
}

XTUint32 SYSCALL::XTTime(time_t *t)
{
		return time(t);
}

XTUint32 SYSCALL::XTTimes(struct tms *buf)
{
		return times(buf);
}

XTInt32 SYSCALL::XTGetrlimit(XTInt32 resource, struct rlimit *rlim)
{
		return getrlimit(resource, rlim);
}

XTInt32 SYSCALL::XTSetrlimit(XTInt32 resource, const struct rlimit *rlim)
{
		return setrlimit(resource, rlim);
}

XTInt32 SYSCALL::XTGetrusage(XTInt32 who, struct rusage *usage)
{
		return getrusage(who, usage);
}

XTInt32 SYSCALL::XTUname(struct utsname *buf)
{
		return uname( buf );
}

XTInt32 SYSCALL::XTRename(XTPStr oldpath, XTPStr newpath)
{
		return rename( oldpath, newpath );
}

XTInt32 SYSCALL::XTUnlink( XTPStr pathname )
{
		return unlink( pathname );
}
												
XTInt32 SYSCALL::XTReadlink(const XTPStr path, XTPStr buf, XTUint32 bufsiz)
{
		return readlink( path, buf, bufsiz );
}
												
void SYSCALL::XTExit(XTInt32 status)
{
		return exit( status );
}

XTInt32 SYSCALL::XTLseek(XTInt32 fd, XTInt32 offset, XTInt32 whence)
{
		return lseek( fd, offset, whence );
}
												
XTInt32 SYSCALL::XTStat(const XTPStr file_name, struct stat *buf)
{
		return stat( file_name, buf );
}

XTInt32 SYSCALL::XTFstat(XTInt32 filedes, struct stat *buf)
{
		return fstat( filedes, buf );
}

void *SYSCALL::XTMmap(void *start, XTUint32 length, XTInt32 prot, XTInt32 flags, XTInt32 fd, XTInt32 offset)
{
		return mmap( start, length, prot, flags, fd, offset );
}
												
void *SYSCALL::XTMremap(void *old_address, XTUint32 old_size, XTUint32 new_size, XTUint32 flags)
{
		return mremap( old_address, old_size, new_size, flags );
}

XTInt32 SYSCALL::XTMunmap(void *start, XTUint32 length)
{
		return munmap(start, length);
}

XTInt32 SYSCALL::XTBrk(void *end_data_segment)
{
		if( end_data_segment == 0 )
				return sys_brk;
	//	assert( (XTMemAddr)end_data_segment >= sys_brk && "end_data_segment should >= sys_brk" );
		if( (XTMemAddr)end_data_segment < original_brk ) {
			assert(0&&"XTERROR ORIGINAL_BRK");
			return -ENOMEM;
		}

		//XXX need to check the argmument
		if( (XTMemAddr)end_data_segment < sys_brk ) {
			UTIL::XTMemset( (void *)end_data_segment , 0 , sizeof(char) * (sys_brk - (XTMemAddr)end_data_segment) );
		 }


		sys_brk = (XTMemAddr)end_data_segment;

		return sys_brk;;
}

XTInt32 SYSCALL::XTSigaction(XTInt32 signum, const struct sigaction *act, struct sigaction *oldact)
{
	return sigaction(signum, act, oldact);
}


XTInt32 SYSCALL::XTSigfillset(sigset_t *sig_set)
{
	return sigfillset(sig_set);
}

XTInt32 SYSCALL::XTSigemptyset(sigset_t *sig_set)
{
	return sigemptyset(sig_set);
}

XTInt32 SYSCALL::XTSigprocmask(XTInt32 how, const sigset_t *sig_set,sigset_t *sig_oldset)
{
	return sigprocmask(how, sig_set, sig_oldset);
}

XTInt32 SYSCALL::XTSigpending(sigset_t *sig_set)
{
	return sigpending(sig_set);
}
